package com.ft.mybatis.domain.repositories.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.ft.core.domain.entities.IEntity;
import com.ft.core.function.Func_1;
import com.ft.core.utils.AutoMapUtils;
import org.apache.ibatis.session.SqlSession;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * @copyright (C), 2015-2019, XXX有限公司
 * @fileName: IMybatisBaseMapper
 * @author: 李阳
 * @date: 2019/6/26 16:54
 * @description: 扩展BaseMapper
 * @history: <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
public interface IMybatisBaseMapper<TEntity extends IEntity> extends BaseMapper<TEntity> {

    /**
     * 批量插入
     *
     * @param entityList ignore
     * @param batchSize  ignore
     * @param insertClass ignore
     * @return ignore
     */
    @Transactional(rollbackFor = Exception.class)
    default boolean insertBatch(Collection<TEntity> entityList, int batchSize, Class<?> insertClass) {
        String sqlStatement = SqlHelper.table(insertClass).getSqlStatement(SqlMethod.INSERT_ONE.getMethod());
        try (SqlSession batchSqlSession = SqlHelper.sqlSessionBatch(insertClass)) {
            int i = 0;
            for (TEntity anEntityList : entityList) {
                batchSqlSession.insert(sqlStatement, anEntityList);
                if (i >= 1 && i % batchSize == 0) {
                    batchSqlSession.flushStatements();
                }
                i++;
            }
            batchSqlSession.flushStatements();
        }
        return true;
    }

    /**
     * 分页查询
     *
     * @param pageIndex    页码
     * @param pageSize     页大小
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     * @param uClass       目标类型
     */
    default <U> IPage<U> selectPage(long pageIndex, long pageSize, Wrapper<TEntity> queryWrapper, Class<U> uClass) {
        Page page = new Page(pageIndex, pageSize);
        IPage pageResult = this.selectPage(page, queryWrapper);
        pageResult.setRecords(AutoMapUtils.mapList(pageResult.getRecords(), uClass));
        return pageResult;
    }

    /**
     * 分页查询
     *
     * @param pageIndex    页码
     * @param pageSize     页大小
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     * @param func         委托
     */
    default <U> IPage<U> selectPage(long pageIndex, long pageSize, Wrapper<TEntity> queryWrapper, Func_1<List<TEntity>, List<U>> func) {
        Page page = new Page(pageIndex, pageSize);
        IPage pageResult = this.selectPage(page, queryWrapper);
        List<U> apply = func.apply(pageResult.getRecords());
        pageResult.setRecords(apply);
        return pageResult;
    }

}
